package com.bootdo.hjh.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bootdo.common.annotation.Log;
import com.bootdo.common.utils.MD5Utils;
import com.bootdo.common.utils.PageUtils;
import com.bootdo.common.utils.PointTradeType;
import com.bootdo.common.utils.R;
import com.bootdo.hjh.cache.MemberCache;
import com.bootdo.hjh.cache.Node;
import com.bootdo.hjh.domain.BankCard;
import com.bootdo.hjh.domain.CashPointsDO;
import com.bootdo.hjh.domain.ProductPointsDO;
import com.bootdo.hjh.domain.Withdraw;
import com.bootdo.hjh.ex.BizException;
import com.bootdo.hjh.service.BankCardService;
import com.bootdo.hjh.service.PointsService;
import com.bootdo.hjh.vo.CashPointVO;
import com.bootdo.hjh.vo.ProductPointVO;
import com.bootdo.hjh.vo.TransferVO;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.service.UserService;
import com.google.common.collect.Maps;

/**
 * Created by qingyong on 2018/3/31.
 */
@Controller
public class PointsController {
	
	@Autowired
	private BankCardService bankCardService;
	@Autowired
    UserService userService;
	
	@Autowired
	private PointsService pointsService;
	
	@Autowired
	private MemberCache memberCache;
	
	private static final Logger logger = LoggerFactory.getLogger(PointsController.class);


    @Log("现金积分-提现-页面跳转")
    @GetMapping("/cash_withdraw")
    public String withdrawUrl(Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        
        Integer cashPointsTotal = pointsService.cashPointsTotal(userId);
		model.addAttribute("cashPointsTotal", cashPointsTotal);
        
        List<BankCard> bankCardList = bankCardService.list(userId);
        model.addAttribute("bankCardList", bankCardList);
        return "hjh/tixian";
    }
    
    @Log("现金积分-提现")
    @PostMapping("/cash_withdraw")
    @ResponseBody
    public R withdraw(Model model,@RequestBody Withdraw withdraw){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        if(withdraw.getAmount() < 100) {
        		return R.error(101, "提现金额最低100元");
        }
        if(withdraw.getPayPwd() == null) {
        		return R.error( "交易密码不能为空");
        }
        UserDO user = userService.get(userId);
        if(user.getPayPwd() == null) {
        		return R.error( "您还未设置交易密码,请先到个人中心设置交易密码");
        }
        String currPayPwd = MD5Utils.encrypt(withdraw.getPayPwd());
        if(!user.getPayPwd().equals(currPayPwd)) {
        		return R.error( "交易密码错误");
        }
        withdraw.setUserId(userId);
        //校验总金额是否够提现金额
        Integer totalCash = pointsService.cashPointsTotal(userId);
        if(withdraw.getAmount().intValue() > totalCash) {
        		return R.error( "余额不足");
        }
        pointsService.withdraw(withdraw);

        return new R();
    }
    
    @Log("现金积分-转账")
    @GetMapping("/cash_transfer")
    public String cashTransferUrl(Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        
        return "hjh/cash_transfer";
    }
    
    @Log("现金积分-转账")
    @PostMapping("/cash_transfer")
    @ResponseBody
    public R cashTransfer(@RequestBody TransferVO transferVO){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        R result = R.ok();
        if(transferVO.getPayPwd() == null) {
            return R.error( 104, "交易密码不能为空");
        }
        UserDO user = userService.get(userId);
        if(user.getPayPwd() == null) {
            return R.error( 104, "您还未设置交易密码,请先到个人中心设置交易密码");
        }
        String currPayPwd = MD5Utils.encrypt(transferVO.getPayPwd());
        if(!user.getPayPwd().equals(currPayPwd)) {
            return R.error( 104,"交易密码错误");
        }
        try{
            pointsService.cashPointTransfer(userId,user.getUsername(),transferVO.getOther(),transferVO.getRealname(),transferVO
                    .getEdu());
        }catch(BizException ex){
            result = R.error(ex.getCode(),ex.getMessage());
        }
        return result;
    }
    
    @Log("现金积分--明细列表")
    @GetMapping("/cash_points_list")
    public String cashList(){
//        //获取当前用户
//        Subject subject = SecurityUtils.getSubject();
//        Map<String,Object> recomment = Maps.newHashMap();
//        Object obj = subject.getPrincipal();
//        Long userId = ((UserDO)obj).getUserId();
//        String username = ((UserDO)obj).getUsername();
//
//        Date begin = null;
//        Date end = null;
//        try{
//            if(StringUtils.isNotBlank(beginDate)){
//                begin = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate);
//            }
//            if(StringUtils.isNotBlank(endDate)){
//                end = (new SimpleDateFormat("yyyy-MM-dd")).parse(endDate);
//            }
//        }catch(Exception ex){
//        }
//
//        List<CashPointsDO> list = pointsService.listCashPoints(userId,type,begin,end);
//        int total = pointsService.countCashPoint(userId,type,begin,end);
//
//        model.addAttribute("type",type);
//        model.addAttribute("cashPoints",convert(list,username));
//        model.addAttribute("total",total);
//
//        model.addAttribute("beginDate",beginDate);
//
//        model.addAttribute("beginDate",beginDate==null?"":beginDate);
//
//        model.addAttribute("endDate",endDate==null?"":endDate);

        return "hjh/cashJifenList";
    }

    @Log("现金积分--明细列表")
    @GetMapping("/cash_points_page/list")
    @ResponseBody
    public PageUtils cashListPage(@RequestParam(value = "type",defaultValue = "0") Integer type
            , @RequestParam(value = "beginDate",required = false) String beginDate
            , @RequestParam(value = "endDate",required = false) String endDate
            , @RequestParam("offset") Integer offset
            , @RequestParam("limit") Integer limit){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        String username = ((UserDO)obj).getUsername();

        Date begin = null;
        Date end = null;
        try{
            if(StringUtils.isNotBlank(beginDate)){
                begin = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate);
            }
            if(StringUtils.isNotBlank(endDate)){
                end = (new SimpleDateFormat("yyyy-MM-dd")).parse(endDate);
            }
        }catch(Exception ex){
        }

        List<CashPointsDO> list = pointsService.listCashPoints(userId,type,begin,end,offset,limit);
        int total = pointsService.countCashPoint(userId,type,begin,end);

        List<CashPointVO> vos = convert(list);

        PageUtils pageUtils = new PageUtils(vos, total);

        return pageUtils;

    }

    private List<CashPointVO> convert(List<CashPointsDO> data){
        if(data==null) return null;
        List<CashPointVO> list = new ArrayList<>(data.size());

        for (CashPointsDO cashPointsDO : data) {
            CashPointVO vo = new CashPointVO();
            if(cashPointsDO.getAmount()!=null){
                vo.setAmount(new java.text.DecimalFormat("#0.00").format(cashPointsDO.getAmount()/100.0));
            }
            vo.setId(cashPointsDO.getId());
            Node node = memberCache.getNodeInCache(cashPointsDO.getUserId());
            cashPointsDO.setUsername(node.getInfo().getUsername());
            vo.setMemberName(cashPointsDO.getReciprocalName() == null? "-" : cashPointsDO.getReciprocalName());
            if(cashPointsDO.getServiceCharge()!=null && cashPointsDO.getServiceCharge()>0){
                vo.setServiceCharge(new java.text.DecimalFormat("#0.00").format(cashPointsDO.getServiceCharge()/100.0));
                vo.setTrueAmount(new java.text.DecimalFormat("#0.00").format((cashPointsDO.getAmount()+cashPointsDO.getServiceCharge())/100.0));
            }else{
                vo.setServiceCharge("0.00");
                vo.setTrueAmount(new java.text.DecimalFormat("#0.00").format((cashPointsDO.getAmount()+cashPointsDO.getServiceCharge())/100.0));
            }
            vo.setUsername(node.getInfo().getUsername());
            vo.setOperateDate(cashPointsDO.getCreateTime());
            vo.setItype(cashPointsDO.getType());
            vo.setType(PointTradeType.getTypeDesc(cashPointsDO.getType()));
            //vo.setType(cashPointsDO.getType()==1?"提现":cashPointsDO.getType()==2?"转账":"分红");
            vo.setRemark(cashPointsDO.getRemark());
            list.add(vo);
        }
        return list;
    }
    
    @Log("商品积分-转账")
    @GetMapping("/product_transfer")
    public String productTransferUrl(Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        
        return "hjh/product_transfer";
    }
    
    @Log("商品积分-转账")
    @PostMapping("/product_transfer")
    @ResponseBody
    public R productTransfer(@RequestBody TransferVO transferVO){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();

        R result = R.ok();
        if(transferVO.getPayPwd() == null) {
            return R.error( 104, "交易密码不能为空");
        }
        UserDO user = userService.get(userId);
        if(user.getPayPwd() == null) {
            return R.error( 104, "您还未设置交易密码,请先到个人中心设置交易密码");
        }
        String currPayPwd = MD5Utils.encrypt(transferVO.getPayPwd());
        if(!user.getPayPwd().equals(currPayPwd)) {
            return R.error( 104, "交易密码错误");
        }
        try{
            pointsService.productPointTransfer(userId,user.getUsername(),transferVO.getOther(),transferVO.getRealname(),transferVO.getEdu());
        }catch(BizException ex){
            result = R.error(ex.getCode(),ex.getMessage());
        }

        return new R();
    }
    
    @Log("商品积分--明细列表")
    @GetMapping("/product_points_list")
    public String productList(Model model,@RequestParam(value = "type",defaultValue = "0") Integer type ,
                              @RequestParam(value = "beginDate",required = false) String beginDate,
                              @RequestParam(value = "endDate",required = false) String endDate){
        //获取当前用户
//        Subject subject = SecurityUtils.getSubject();
//        Map<String,Object> recomment = Maps.newHashMap();
//        Object obj = subject.getPrincipal();
//        Long userId = ((UserDO)obj).getUserId();
//        String username = ((UserDO)obj).getUsername();
//        Date begin = null;
//        Date end = null;
//        try{
//            if(StringUtils.isNotBlank(beginDate)){
//                begin = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate);
//            }
//            if(StringUtils.isNotBlank(endDate)){
//                end = (new SimpleDateFormat("yyyy-MM-dd")).parse(endDate);
//            }
//        }catch(Exception ex){
//        }
//        List<ProductPointsDO> list = pointsService.listProductPoints(userId,type,begin,end);
//        int total = pointsService.countProductPoint(userId,type,begin,end);
//
//        model.addAttribute("type",type);
//        model.addAttribute("productPoints",convertProductPoint(list,username));
//        model.addAttribute("total",total);
//
//        model.addAttribute("beginDate",beginDate==null?"":beginDate);
//
//        model.addAttribute("endDate",endDate==null?"":endDate);
        
        return "hjh/productJifenList";
    }

    @Log("商品积分--明细列表")
    @GetMapping("/product_points_page/list")
    @ResponseBody
    public PageUtils productListPage(@RequestParam(value = "type",defaultValue = "0") Integer type ,
                              @RequestParam(value = "beginDate",required = false) String beginDate,
                              @RequestParam(value = "endDate",required = false) String endDate
            , @RequestParam("offset") Integer offset
            , @RequestParam("limit") Integer limit){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        Map<String,Object> recomment = Maps.newHashMap();
        Object obj = subject.getPrincipal();
        Long userId = ((UserDO)obj).getUserId();
        String username = ((UserDO)obj).getUsername();

        Date begin = null;
        Date end = null;
        try{
            if(StringUtils.isNotBlank(beginDate)){
                begin = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate);
            }
            if(StringUtils.isNotBlank(endDate)){
                end = (new SimpleDateFormat("yyyy-MM-dd")).parse(endDate);
            }
        }catch(Exception ex){
        }

        List<ProductPointsDO> list = pointsService.listProductPoints(userId,type,begin,end,offset,limit);
        int total = pointsService.countCashPoint(userId,type,begin,end);

        List<ProductPointVO> vos = convertProductPoint(list,username);

        PageUtils pageUtils = new PageUtils(vos, total);

        return pageUtils;
    }
    private List<ProductPointVO> convertProductPoint(List<ProductPointsDO> data, String username){
        if(data==null) return null;
        List<ProductPointVO> list = new ArrayList<>(data.size());

        for (ProductPointsDO productPointsDO : data) {
            ProductPointVO vo = new ProductPointVO ();
            if(productPointsDO.getAmount()!=null){
                vo.setAmount(new java.text.DecimalFormat("#0.00").format(productPointsDO.getAmount()/100.0));
            }
            vo.setId(productPointsDO.getId());
            vo.setMemberName(productPointsDO.getReciprocalName() == null ? "-" : productPointsDO.getReciprocalName());
            vo.setOperateDate(productPointsDO.getCreateTime());
            vo.setItype(productPointsDO.getType());
            vo.setType(PointTradeType.getTypeDesc(productPointsDO.getType()));
            vo.setRemark(productPointsDO.getRemark());
            list.add(vo);
        }
        return list;
    }
    
    @GetMapping("/points/sys_cash_points_page")
    public String sysCashPointsList(){
    		
        return "hjh/sys_cash_list";
    }
    
    @GetMapping("/points/sys_cash_points_list")
    @ResponseBody
    public PageUtils sysCashPointsList(@RequestParam(value = "type",defaultValue = "0") Integer type ,
            @RequestParam(value = "beginDate",required = false) String beginDate,
            @RequestParam(value = "endDate",required = false) String endDate
            , @RequestParam("offset") Integer offset
            , @RequestParam("limit") Integer limit
            , @RequestParam(value="userId",required = false)  Long userId
            , @RequestParam(value="username",required = false)  String username){
    		Date begin = null;
        Date end = null;
        try{
            if(StringUtils.isNotBlank(beginDate)){
                begin = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate);
            }
            if(StringUtils.isNotBlank(endDate)){
                end = (new SimpleDateFormat("yyyy-MM-dd")).parse(endDate);
            }
        }catch(Exception ex){
        }
        if(userId == null) {
        	if(!org.apache.commons.lang3.StringUtils.isEmpty(username)) {
        		UserDO userDO = userService.getByUsername(username);
        		if(null != userDO) {
        			userId = userDO.getUserId();
        		}else {
        			userId = -1l;
        		}
        	}
        }
        List<CashPointsDO> list = pointsService.listCashPoints(userId,type,begin,end,offset,limit);
        int total = pointsService.countCashPoint(userId,type,begin,end);
        List<CashPointVO> vos = convert(list);
        PageUtils pageUtils = new PageUtils(vos, total);
        return pageUtils;
    }
    
    @GetMapping("/points/income")
    @ResponseBody
    public R<?> reportIncome(
            @RequestParam(value = "startDate",required = false) String startDate,
            @RequestParam(value = "endDate",required = false) String endDate){
        List<Integer> list = pointsService.reportIncome(startDate, endDate);
        return R.ok().list(list);
    }
    
    @GetMapping("/points/expend")
    @ResponseBody
    public R<?> reportExpend(
            @RequestParam(value = "startDate",required = false) String startDate,
            @RequestParam(value = "endDate",required = false) String endDate){
        List<Integer> list = pointsService.reportExpend(startDate, endDate);
        return R.ok().list(list);
    }
    
    
    @GetMapping("/points/income_month")
    @ResponseBody
    public R<?> reportIncomeMonth(
            @RequestParam(value = "startDate",required = false) String startDate,
            @RequestParam(value = "endDate",required = false) String endDate){
        List<Integer> list = pointsService.reportIncomeMonth(startDate, endDate);
        return R.ok().list(list);
    }
    
    @GetMapping("/points/expend_month")
    @ResponseBody
    public R<?> reportExpendMonth(
            @RequestParam(value = "startDate",required = false) String startDate,
            @RequestParam(value = "endDate",required = false) String endDate){
        List<Integer> list = pointsService.reportExpendMonth(startDate, endDate);
        logger.info("list : {}",list);
        return R.ok().list(list);
    }
    
    @GetMapping("/points/amount_sum")
    @ResponseBody
    public R<?> amountSum(){
        Map<String, Double> result = pointsService.amountSum();
        return R.ok().domain(result);
    }
    
}
